/*
 * Copyright (C) 2022, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.0
import org.ukui.sidebar.core 1.0
import org.ukui.sidebar.items 1.0
import org.ukui.sidebar.ui 1.0

Item {
    id:root;
    // 初始高度  ->不定义会重合
    height: isNotificationCenter ? 120 : 108;

    property string appName: "";
    property int index: 0;
    property bool boxFold: layout.fold;
    property int radius: isNotificationCenter ? 24 : layoutConfig.radius(LayoutComponent.NotificationItem);

    signal messageCleared();

    Component {
        id: messageItemComponent
        MessageItem {}
    }

    //创建组件  插入新消息
    function addMessage(message) {
        let obj = messageItemComponent.createObject(null, {id:message.id
                                             ,appName:message.appName
                                             ,notificationIcon:message.notificationIcon
                                             ,summary:message.summary
                                             ,body:message.body
                                             ,timeStamp:message.timeStamp}); //获取数据

        layout.insertItem(obj);
    }

    //消息组清除
    function destroyMessageBox() {
        root.messageCleared();
    }

    function syncDeleteMessage(id) {
        layout.deleteMessage(id);
    }

    Behavior on height {
        NumberAnimation {
            easing.type: Easing.InOutQuint
            duration: 350;
        }
    }

    // 滑出区域后有圆角属性
    layer.enabled: isOpenGLEnv;
    layer.effect: OpacityMask {
        maskSource: Rectangle {
            width: root.width;
            height: root.height;
            radius: root.radius;
        }
    }

    Item {
        id: boxContainer;
        height: root.height;
        width: root.width;
        x: 0;
        y: 0;

        MessageFold {
            id: messageFold;
            anchors.horizontalCenter: boxLayout.horizontalCenter;
            width: parent.width;
            x: 0;
            y: 0;
            z: -1;
            layoutCount: layout.count;

            onLayoutCountChanged: {
                if (layoutCount === 1) {
                    messageFold.height = fakeHeight;
                } else if (layoutCount === 2) {
                    messageFold.height = fakeHeight + spacing;
                } else {
                    messageFold.height = fakeHeight + spacing * 2;
                    if(boxFold) {
                        root.height = messageFold.height;
                    }
                }
            }
        }

        //消息组及折叠后顶部按钮 布局
        Column {
            id: boxLayout;
            anchors.fill: parent;
            spacing: 8;
            state: "";

            states: [
                State {
                    name: "Folded";
                    PropertyChanges {
                        target: clickUnfolded;
                        enabled: true;
                    }
                    PropertyChanges {
                        target: functionButton;
                        visible: false;
                        opacity: 0;
                    }
                    PropertyChanges {
                        target: messageFold;
                        visible: true;
                    }
                    PropertyChanges {
                        target: layout;
                        fold: true;
                    }
                },
                State {
                    name: "Unfolded";
                    PropertyChanges {
                        target: functionButton;
                        visible: true;
                        opacity: 1.0;
                    }
                    PropertyChanges {
                        target: clickUnfolded;
                        enabled: false;
                    }
                    PropertyChanges {
                        target: messageFold;
                        visible: false;
                    }
                    PropertyChanges {
                        target: layout;
                        fold: false;
                    }
                },
                State {
                    name: "Quantum";
                    PropertyChanges {
                        target: functionButton;
                        visible: false;
                        opacity: 0.0;
                    }
                    PropertyChanges {
                        target: clickUnfolded;
                        enabled: false;
                    }
                    PropertyChanges {
                        target: messageFold;
                        visible: false;
                    }
                    PropertyChanges {
                        target: layout;
                        fold: false;
                    }
                },
                State {
                    name: "AntiQuantum";
                    PropertyChanges {
                        target: functionButton;
                        visible: false;
                        opacity: 0.0;
                    }
                    PropertyChanges {
                        target: clickUnfolded;
                        enabled: true;
                    }
                    PropertyChanges {
                        target: messageFold;
                        visible: true;
                    }
                    PropertyChanges {
                        target: layout;
                        fold: true;
                    }
                }
            ]

            move: Transition {
                NumberAnimation {
                    property: "y";
                    easing.type: Easing.InOutSine
                    duration: 300;
                }
            }

            onStateChanged: {
                if(boxLayout.state === "Folded") {
                    if(layout.count === 2) {
                        root.height = layout.itemFoldHeight + 8;
                    } else {
                        root.height = layout.itemFoldHeight + 16;
                    }
                } else if (boxLayout.state === "AntiQuantum") {
                    root.height =  layout.itemFoldHeight + 8;
                } else if (boxLayout.state === "Quantum") {
                    root.height =  layout.itemHeight;
                } else {
                    root.height = layout.itemHeight * layout.count + functionButton.height + spacing *layout.count;
                }
            }

            //顶部按钮  折叠、清空
            Item {
                id: functionButton;
                width: layout.width;
                height: isNotificationCenter ? 48 : 36;
                opacity: visible;
                visible: false;
                anchors.horizontalCenter: parent.horizontalCenter;

                StyleBackground {
                    id: foldedButton;
                    height: functionButton.height;
                    radius: isNotificationCenter ? functionButton.height /2 : 6;
                    paletteRole: PaletteRole.Base;
                    property int spacing: 8;

                    HighlightIcon {
                        id: showLessIcon;
                        height: 20;
                        width: height;
                        anchors.left: foldedButton.left;
                        anchors.leftMargin: foldedButton.spacing*2;
                        anchors.verticalCenter: foldedButton.verticalCenter;

                        iconName: "ukui-up-symbolic";
                    }

                    StyleText {
                        id: showLessText;
                        anchors.left: showLessIcon.right;
                        anchors.leftMargin: foldedButton.spacing;
                        anchors.verticalCenter: foldedButton.verticalCenter;

                        font.pixelSize: 16;
                        text: qsTr("Show less");
                        elide: Text.ElideRight;
                    }

                    Component.onCompleted: {
                        let maxWidth = functionButton.width - clear.width;

                        let textWidth = showLessText.contentWidth;
                        let maxTextWidth = maxWidth - showLessIcon.width - foldedButton.spacing*5;
                        showLessText.width = Math.min(maxTextWidth, textWidth);

                        let realWidth = showLessText.width + showLessIcon.width + spacing * 5;
                        width = Math.max(Math.min(maxWidth, realWidth), functionButton.height * 2);
                    }

                    MouseArea {
                        anchors.fill: parent;
                        onClicked: {
                            boxLayout.state = "Folded";
                        }
                    }
                }

                //平板模式下清空按钮
                StyleBackground {
                    id: clear;
                    height: functionButton.height;
                    width:  clear.height
                    radius:  clear.height /2;
                    anchors.right: functionButton.right;
                    anchors.verticalCenter: functionButton.verticalCenter;
                    visible: isNotificationCenter;
                    useStyleTransparency: false;
                    alpha: 0.85;

                    HighlightIcon {
                        height: 16;
                        width: height;
                        anchors.centerIn: parent;
                        forceHighlight: true;

                        iconName: "window-close-symbolic";
                    }
                    MouseArea {
                        hoverEnabled: true;
                        anchors.fill: parent;
                        onClicked: {
                            clearGroup.start();
                            clearGroupOpacity.start();
                        }
                        onEntered: {
                            clear.alpha = 1.0;
                        }
                        onPressed: {
                            clear.alpha = 0.65;
                        }
                        onReleased: {
                            clear.alpha = 0.85;
                        }
                        onExited: {
                            clear.alpha = 0.85;
                        }
                        onCanceled: {
                            clear.alpha = 0.85;
                        }
                    }
                }

                //pc侧边栏清空按钮
                GeneralButton {
                    id: closeButton;
                    width: 24;
                    height: width;
                    radius: 16;
                    anchors.right: functionButton.right;
                    anchors.rightMargin: 6;
                    anchors.verticalCenter: functionButton.verticalCenter;
                    iconName: "window-close-symbolic"
                    visible: !isNotificationCenter;

                    layer.enabled: false;
                    layer.effect: DropShadow {
                        visible: false;
                        radius: 8.0;
                        samples: 20
                        color: "#808080";
                    }
                    onClicked: {
                        clearGroup.start();
                        clearGroupOpacity.start();
                    }
                    onEntered: {
                        layer.enabled = isOpenGLEnv;
                    }
                    onExited: {
                        layer.enabled = false;
                    }
                }

                Behavior on opacity {
                    NumberAnimation{
                        duration: 300;
                    }
                }
            }
            //折叠后消息组 点击、滑动
            Item {
                id: messageLayoutContainer;
                width: parent.width;
                height: layout.height;

                MouseArea {
                    id: clickUnfolded;
                    anchors.fill: parent;
                    enabled: true;

                    //鼠标点击展开在item上面覆盖
                    z :1;
                    onClicked: {
                        boxLayout.state = "Unfolded";
                    }
                    //折叠状态下右上角点击删除区域
                    Item {
                        width: 30;
                        height: 30;
                        anchors.top: clickUnfolded.top;
                        anchors.right: clickUnfolded.right;
                        visible: !isNotificationCenter && boxFold;

                        MouseArea {
                            anchors.fill: parent;
                            onClicked: {
                                moved.start();
                            }
                        }
                    }
                }

                //消息组自定义布局
                MessageLayout {
                    id: layout;
                    width: parent.width;
                    anchors.horizontalCenter: parent.horizontalCenter;
                    Behavior on height {
                        NumberAnimation{
                            easing.type: Easing.InOutQuint
                            duration: 350;
                        }
                    }
                    //点击清空按钮后 消息组动画
                    NumberAnimation {
                        id: clearGroup;
                        targets: [layout,functionButton];
                        easing.type: Easing.InOutSine
                        properties: "y";
                        to: - (layout.height + functionButton.height + boxLayout.spacing);
                        duration: 300;

                        onFinished: {
                            root.destroyMessageBox();
                        }
                    }
                    NumberAnimation {
                        id: clearGroupOpacity;
                        targets: root;
                        properties: "opacity,height";
                        to: 0;
                        duration: 300;
                        easing.type: Easing.InOutSine;
                    }

                    spacing: 8;
                    clip: true;
                    //折叠按钮 显示 隐藏 /消息组折叠展开 /box高度变化 --根据消息数量变化
                    onCountChanged: {
                        if (count > 2) {
                            if (fold) {
                                foldedMessage();
                                root.height = messageFold.height;
                            } else {
                                forceLayout();
                                root.height = layout.itemHeight * layout.count + functionButton.height + spacing *layout.count;
                            }
                        } else if (count === 2) {
                            if(functionButton.visible ===false) {
                                boxLayout.state = "AntiQuantum";
                            } else {
                                forceLayout();
                                root.height = layout.itemHeight * 2 + spacing *layout.count + functionButton.height;
                            }
                        } else if (count === 1) {
                            boxLayout.state = "Quantum";
                            layout.height = itemHeight;
                        } else {
                            destroyMessageBox();
                        }
                    }
                }
            }
        }
    }

    // 控制滑动条组左右滑动的鼠标区域
    MouseArea {
        id: boxMouseArea
        height: parent.height;
        width: removeButton.visible ? (parent.width - removeButton.width): parent.width;
        enabled: boxFold;
        propagateComposedEvents: false;
        state: "ViewMove";

        property int dragBoxStartX: 0 ; //鼠标拖动box起始 位置
        property int dragMouseStartX: 0 ; //鼠标拖动起始 位置
        property int dragMouseStartY: 0 ;
        property bool moveState: false;


        function boxMove() {
            //没有鼠标按下事件时，进行左右移动和上下移动的判断
            if (!moveState) {
                if (Math.abs(mouseX - dragMouseStartX) > 3 || Math.abs(mouseY - dragMouseStartY) > 3) {
                    if (Math.abs(mouseX - dragMouseStartX) > Math.abs(mouseY - dragMouseStartY)) {
                        boxMouseArea.state = "BoxMove";
                    } else {
                        boxMouseArea.state = "ViewMove";
                    }
                    moveState = true;
                }
            }
        }

        states: [
            State {
                name: "BoxMove"
                PropertyChanges {
                    target: boxMouseArea;
                    preventStealing: true;
                }
            },
            State {
                name: "ViewMove"
                PropertyChanges {
                    target: boxMouseArea;
                    preventStealing: false;
                }
            }
        ]

        onClicked: {
            mouse.accepted = false;
        }

        onPressed: {
            moveState = false;
            dragBoxStartX = boxContainer.x;
            dragMouseStartX = mouseX;
            dragMouseStartY = mouseY;
        }

        onPositionChanged: {
            boxMove();
            if (boxMouseArea.state === "BoxMove") {
                boxContainer.x = Math.floor(dragBoxStartX + (mouseX - dragMouseStartX));

                if (boxContainer.x < -removeButton.width) {
                    removeButton.visible = true;
                    removeButton.opacity = 0.85;
                } else {
                    removeButton.opacity = 0;
                    removeButton.visible = false;
                }
            }
        }

        onReleased: {
             boxMouseArea.state = "ViewMove";
            // 鼠标位移量小 -->点击事件 ==》鼠标穿透，boxContainer点击展开
            if (Math.abs(mouseX - dragMouseStartX) < 3 &&0 < mouseY && mouseY< boxContainer.height && boxContainer.x ===0) {
                boxMouseArea.propagateComposedEvents = true;
            } else {
                boxMouseArea.propagateComposedEvents = false;
                if (boxContainer.x >= -removeButton.width /2 ) {
                    //右滑返回
                    back.start();
                    removeButton.opacity = 0;
                    removeButton.visible = false;

                } else if ( boxContainer.x < -removeButton.width /2 && boxContainer.x > -boxContainer.width /3 ) {
                    //小幅左滑显示删除按钮
                    appear.start();
                    removeButton.opacity = 0.85;
                    removeButton.visible = true;

                } else {
                    //大幅左滑直接删除，不显示删除按钮
                    moved.start();
                    removeButton.opacity = 0;
                    removeButton.visible = false;
                }
            }
        }
    }

    StyleBackground  {
        id: removeButton;

        height: 120;
        width: height;
        radius: width /2;
        visible: false;
        opacity: 0;
        useStyleTransparency: false;
        anchors.verticalCenter: parent.verticalCenter;
        anchors.right: root.right;

        // 深色主题下反色
        HighlightIcon {
            height: 24;
            width: height;
            anchors.centerIn: parent;
            forceHighlight: true;
            iconName: "window-close-symbolic";
        }

        MouseArea {
            anchors.fill: parent;
            hoverEnabled: true;
            visible: removeButton.visible;

            function restore() {
                removeButton.alpha = 0.85;
            }
            onClicked: {
                moved.start();
            }
            onEntered: {
                removeButton.alpha = 1.0;
            }
            onExited: {
                restore();
            }
            onPressed: {
                removeButton.alpha = 0.65;
            }
            onReleased: {
                restore();
            }
            onCanceled: {
                restore();
            }
        }

        Behavior on opacity {
            PropertyAnimation {
                duration: 400;
                easing.type: Easing.Linear;
            }
        }
    }

    NumberAnimation {
        id: back;
        target: boxContainer;
        properties: "x";
        to: 0;
        duration: 400;
    }

    NumberAnimation {
        id: appear;
        target: boxContainer;
        properties: "x";
        to: -(removeButton.width + 8);
        duration: 400;
    }

    NumberAnimation {
        id: moved;
        target: boxContainer;
        properties: "x";
        to: - boxContainer.width;
        duration: 400;

        onFinished: {
            destroyMessageBox();
        }
    }
}
